using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Web.Hosting;
using Toast.Core;
using Toast.Core.Interfaces;
using Toast.Extensions;
using Toast.Utils;

namespace Toast.ContentTypes
{
    public sealed class LocalJavaScriptFile : JavaScriptContentBase, ICompressable
    {
        readonly string _fullPath;

        public LocalJavaScriptFile()
        {
        }

        // TODO: Add IfIE support

        internal LocalJavaScriptFile(string scriptPath, InjectAt injectAt, ICompressionStrategy javaScriptCompression, Func<bool> injectIf)
        {
            OriginalPath = Utility.CleanPath(scriptPath);
            InjectAt = injectAt;
            FileName = Path.GetFileName(scriptPath);
            Compression = javaScriptCompression;
            _fullPath = HostingEnvironment.MapPath(OriginalPath);
            InjectIf = injectIf;
        }

        public string OriginalPath { get; set; }
        public string Content { get; set; }

        public string FullPath
        {
            get { return _fullPath; }
        }

        public override IInjectionFormatter GetFormatter(string packageKey)
        {
            return new LocalFileFormatter(packageKey, "<script type='text/javascript' src='{0}'></script>");
        }

        public override bool TryConstructFrom(string from, out IContent result)
        {
            if (!Regex.IsMatch(from, @"^[\\/\a-zA-Z\-][^\:]+js"))
            {
                result = null;
                return false;
            }

            var orignalPath = Utility.CleanPath(from);
            result = FromPath(orignalPath, InjectAt.Default, ToastCore.Compression().ForJavaScript(), null);

            return true;
        }

        public static LocalJavaScriptFile FromPath(string path)
        {
            return FromPath(path, InjectAt.Default);
        }

        public static LocalJavaScriptFile FromPath(string path, Func<bool> injectIf)
        {
            return FromPath(path, InjectAt.Default, ToastCore.Compression().ForJavaScript(), injectIf);
        }

        public static LocalJavaScriptFile FromPath(string path, InjectAt injectAt)
        {
            return FromPath(path, injectAt, ToastCore.Compression().For<IJavaScriptContent>(), null);
        }

        public static LocalJavaScriptFile FromPath(string path, ICompressionStrategy javaScriptCompression)
        {
            return FromPath(path, InjectAt.Default, javaScriptCompression, null);
        }

        public static LocalJavaScriptFile FromPath(string path, InjectAt injectAt, ICompressionStrategy javaScriptCompression, Func<bool> injectIf)
        {
            return File.Exists(HostingEnvironment.MapPath(path))
                       ? new LocalJavaScriptFile(path, injectAt, javaScriptCompression, injectIf)
                       : null;
        }

        public string ToEncodedUrl(string pathFormat, string packageKey)
        {
            return pathFormat.FormatWith(EncodingUtils.UrlSafeEncode(Id.ToString()), packageKey);
        }
    }
}